package buyChance

import (
	"util"
)

type SDds_C2P_PHead struct {
	WPid  uint16 //包ID
	DwLen uint32 //包长度，包含包头
}

type SDdsPYHQ struct {
	Head       SDds_C2P_PHead
	IdMarket   string //uint32//例如"SHHQ"
	IdDyn      uint16 //DDS_Dyn_Data类型
	IdStk      uint32
	WItemSize  uint16 //DDS_Dyn_Data类型对应结构体大小
	DwCount    uint32
	DwReserved [2]uint32
	Data       []byte
}

//主动推送，市场日期列表，重复推送，需判断行情日期是否变化
const PID_DDS_PY_MARKET_DATE_LIST = 6000

type SDdsPYMarketDateListAItem struct {
	IdMarket   string //uint32
	DwHQDate   uint32
	DwReserved uint32
}
type SDdsPYMarketDateListA struct {
	Head       SDds_C2P_PHead
	DwCount    uint32
	DwReserved [2]uint32
	PItem      []SDdsPYMarketDateListAItem
}

//主动推送，代码表变化后推送
const PID_DDS_PY_CN_LIST_20160826 = 6010
const PID_DDS_PY_CN_LIST = 6011

type SDdsPYCNListAItem struct {
	IdStk        uint32
	SzMarketCode string //[13]byte
	SzName       string //[21]byte
}
type SDdsPYCNListA struct {
	Head       SDds_C2P_PHead
	IdMarket   string //uint32
	DwCount    uint32
	DwReserved [2]uint32
	PItem      []SDdsPYCNListAItem
}

const PID_DDS_PY_OPEN_INFO = 6015

type SDdsPYOpenInfoAItem struct {
	IdStk      uint32
	FLastClose float32 //前收价
	FAve5Vol   float32 //5日均量
	FTq        float32 //流通盘
	FDr        float32 //除权系数
}
type SDdsPYOpenInfoA struct {
	Head       SDds_C2P_PHead
	DwDate     uint32
	IdMarket   string //uint32
	DwCount    uint32
	DwReserved [2]uint32
	PItem      []SDdsPYOpenInfoAItem
}

//行情快照包，仅在连接后，发一次全量包
const PID_DDS_PY_SNAP = 6020

type SDdsPYSnanpA SDdsPYHQ

//行情推送包
const PID_DDS_PY_PUSH = 6030

type SDdsPYPushA SDdsPYHQ

//补数包，请求包，一问多答，前一个请求没完成前，不建议发下一个请求包
const PID_DDS_PY_PATCH = 6040

type SDdsPYPatch struct {
	Head     SDds_C2P_PHead
	IdMarket string //uint32
	IdStk    uint32
	IdDyn    uint16

	DwMinDate  uint32 //数据范围
	DwMinTime  uint32 //数据范围
	DwMaxDate  uint32 //数据范围
	DwMaxTime  uint32 //数据范围
	NNeedCount int32  //nNeedCount<0 从后往前  nNeedCount>0 从前往后  nNeedCount==0 从前完后读取全部

	DwReserved [3]uint32
}
type SDdsPYPatchA SDdsPYHQ //应答可能是多个包，空节点(dwCount==0)表示补完

//分价表，请求包，一问一答，前一个请求没完成前，不建议发下一个请求包
const PID_DDS_PY_PRICE_LIST = 6080

type SDdsPYPriceList struct {
	Head     SDds_C2P_PHead
	IdMarket string //uint32
	IdStk    uint32
}
type SDdsPYPriceListAItem struct {
	NPrice      uint32
	FBugVolume  float32
	FSellVolume float32
}
type SDdsPYPriceListA struct {
	Head          SDds_C2P_PHead
	IdMarket      string //uint32
	IdStk         uint32
	DwLastHqTime  uint32
	N64LastVolume int64
	N64LastAmount int64
	WDecm         uint16
	DwCount       uint32
	DwReserved    [3]uint32
	PItem         []SDdsPYPriceListAItem
}

func (s *SDdsPYPatch) Encode() []byte {
	var b []byte
	b = append(b, util.Uint16ToByte(s.Head.WPid)...)
	b = append(b, util.Uint32ToByte(s.Head.DwLen)...)
	b = append(b, ([]byte)(s.IdMarket)...)
	b = append(b, util.Uint32ToByte(s.IdStk)...)
	b = append(b, util.Uint16ToByte(s.IdDyn)...)
	b = append(b, util.Uint32ToByte(s.DwMinDate)...)
	b = append(b, util.Uint32ToByte(s.DwMinTime)...)
	b = append(b, util.Uint32ToByte(s.DwMaxDate)...)
	b = append(b, util.Uint32ToByte(s.DwMaxTime)...)
	b = append(b, util.Int32ToByte(s.NNeedCount)...)
	b = append(b, util.Uint32ToByte(s.DwReserved[0])...)
	b = append(b, util.Uint32ToByte(s.DwReserved[1])...)
	b = append(b, util.Uint32ToByte(s.DwReserved[2])...)
	return b
}

func (s *SDdsPYPriceList) Encode() []byte {
	var b []byte
	b = append(b, util.Uint16ToByte(s.Head.WPid)...)
	b = append(b, util.Uint32ToByte(s.Head.DwLen)...)
	b = append(b, ([]byte)(s.IdMarket)...)
	b = append(b, util.Uint32ToByte(s.IdStk)...)
	return b
}

const DDS_STK_L2_ORDER_COUNT = 10 // 股票L2行情档数
const DDS_STK_L1_ORDER_COUNT = 5  // 股票L2行情档数
const DDS_FTR_L2_ORDER_COUNT = 5  // 期货L2行情档数

//各个市场的行情的委托数量
const DDS_ORDER_QUEUE_COUNT_SH_L2 = 50 //最优委托的最大数量

// 动态数据列表的节点
type SDds_I_DynBase struct {
	IdStk     uint32 //品种ID
	DwDate    uint32 //数据日期
	WDecm     uint16 //价格转换成整数时需要乘的幂数(0～7)，实际乘数应该是 10 exp (wDecm-2)。0:乘0.01  1:乘0.1  2:乘1 3:乘10 ……
	WVolExp   uint16 //计算均价时，成交量需要乘的幂数(0～3)，实际乘数应该是 (10 exp yVolExp)，总的来说成交量的乘数应该是 vol * (10 exp yVolExp) * (yVolMul+1)
	WVolMul   uint16 //计算均价时，成交量需要乘的数字(0～127)，实际乘数应该是 (yVolMul+1)，总的来说成交量的乘数应该是 vol * (10 exp yVolExp) * (yVolMul+1)
	WReserved uint16

	//本域有三种含义：
	//	对于逐笔来说，是一个连续递增的flowid
	//	对于期货L2行情来说，同一秒内有可能有多笔行情，因此采用 hhmmssnn 的格式，其中nn是一个序号，标识同一秒内的第几笔(00～99)
	//	对于其他行情来说，是一般性的时间(hhmmss)
	//union
	//{
	//DWORD				dwTransFlowId;		//单调递增的序号
	//DWORD				dwFtrL2Time;		//hhmmssnn nn表示当前行情是本秒的第几笔
	//DWORD				dwHqTime;			//hhmmss（夜盘的话这里是xhhmmss参见CMarketDateHelper）
	//};
	DwUion uint32
}

func (s *SDds_I_DynBase) Decode(b []byte) {
	s.IdStk = util.Byte2Uint32(b[:4])
	s.DwDate = util.Byte2Uint32(b[4:8])
	Wt := util.Byte2Uint16(b[8:10])
	s.WDecm = Wt & 7
	s.WVolExp = (Wt >> 3) & 3
	s.WVolMul = (Wt >> 5) & 127
	s.WReserved = (Wt >> 12) & 15
	s.DwUion = util.Byte2Uint32(b[10:14])
}

//非K线的开盘信息，此时前后两笔的 开高低是有关系的
type SDds__Hq_O struct {
	NOpen int32 //开盘价
	NHigh int32 //最高价
	NLow  int32 //最低价
}

func (s *SDds__Hq_O) Decode(b []byte) {
	s.NOpen = util.Byte2Int32(b[:4])
	s.NHigh = util.Byte2Int32(b[4:8])
	s.NLow = util.Byte2Int32(b[8:12])
}

type SDds__Hq_KO SDds__Hq_O

func (s *SDds__Hq_KO) Decode(b []byte) {
	s.NOpen = util.Byte2Int32(b[:4])
	s.NHigh = util.Byte2Int32(b[4:8])
	s.NLow = util.Byte2Int32(b[8:12])
}

//K线的收盘信息，前后两笔的 最新价，成交量、额是没有关系的
type SDds__Hq_C struct {
	NNewest int32 //最新价或者是收盘价
	NVolume int64 //成交量
	NAmount int64 //成交额
}

func (s *SDds__Hq_C) Decode(b []byte) {
	s.NNewest = util.Byte2Int32(b[:4])
	s.NVolume = util.Byte2Int64(b[4:12])
	s.NAmount = util.Byte2Int64(b[12:20])
}

//最新价信息，一般来说，这个结构中的成交量和成交额是累加值
type SDds__Hq_N1 struct {
	NNewest int32 //最新价或者是收盘价
	NVolume int64 //成交量
	NAmount int64 //成交额
}

func (s *SDds__Hq_N1) Decode(b []byte) {
	s.NNewest = util.Byte2Int32(b[:4])
	s.NVolume = util.Byte2Int64(b[4:12])
	s.NAmount = util.Byte2Int64(b[12:20])
}

//期货结算价、持仓量信息
type SDds__Hq_Stf struct {
	NSettle int32 //结算价
	NStaff  int64 //持仓量
}

func (s *SDds__Hq_Stf) Decode(b []byte) {
	s.NSettle = util.Byte2Int32(b[:4])
	s.NStaff = util.Byte2Int64(b[4:12])
}

//委托信息
type SDds__Hq_Order struct {
	NPrice int32 //委托价
	NOrder int64 //委托量
}

func (s *SDds__Hq_Order) Decode(b []byte) {
	s.NPrice = util.Byte2Int32(b[:4])
	s.NOrder = util.Byte2Int64(b[4:12])
}

//动态数据——WAV分类成交，	DDS_DYN_DATA_Wav_Cj_Fenshi	DDS_DYN_DATA_Wav_Cj_Day
type SDds__Wav_Cj struct {
	NBCount int32 //买单数
	NBVol   int64 //买单成交量
	NBAmt   int64 //买单成交额

	NSCount int32 //卖单数
	NSVol   int64 //卖单成交量
	NSAmt   int64 //卖单成交额

}

func (s *SDds__Wav_Cj) Decode(b []byte) {
	s.NBCount = util.Byte2Int32(b[:4])
	s.NBVol = util.Byte2Int64(b[4:12])
	s.NBAmt = util.Byte2Int64(b[12:20])
	s.NSCount = util.Byte2Int32(b[20:24])
	s.NSVol = util.Byte2Int64(b[24:32])
	s.NSAmt = util.Byte2Int64(b[32:40])
}

//股票指数的相关信息
type SDds__Hq_Z struct {
	NBidTotalVol int64 //委买总量
	NAskTotalVol int64 //委卖总量
	NUp          int32 //涨家数
	NDown        int32 //跌家数
	NEqual       int32 //平家数
}

func (s *SDds__Hq_Z) Decode(b []byte) {
	s.NBidTotalVol = util.Byte2Int64(b[:8])
	s.NAskTotalVol = util.Byte2Int64(b[8:16])
	s.NUp = util.Byte2Int32(b[16:20])
	s.NDown = util.Byte2Int32(b[20:24])
	s.NEqual = util.Byte2Int32(b[24:28])
}

//股票Level2行情的附加结构
type SDds__Hq_S2 struct {
	NTrans       int64 //成就笔数
	NBidTotalVol int64 //委买总量
	NAskTotalVol int64 //委卖总量
	NBidAvePrice int32 //加权平均委买价格
	NAskAvePrice int32 //加权平均委卖价格
}

func (s *SDds__Hq_S2) Decode(b []byte) {
	s.NTrans = util.Byte2Int64(b[:8])
	s.NBidTotalVol = util.Byte2Int64(b[8:16])
	s.NAskTotalVol = util.Byte2Int64(b[16:24])
	s.NBidAvePrice = util.Byte2Int32(b[24:28])
	s.NAskAvePrice = util.Byte2Int32(b[28:32])
}

// 动态数据——期货Level2行情节点， DDS_DYN_DATA_FTR_HQ_L2
type SDds_I_Dyn_Ftr_L2 struct {
	Info    SDds_I_DynBase                         // 动态数据列表的节点
	O       SDds__Hq_O                             // 开盘信息
	N1      SDds__Hq_N1                            // 最新价信息
	Stf     SDds__Hq_Stf                           // 持仓量相关信息
	NBuyVol int64                                  // 买盘，主卖盘=成交量-主买盘
	Bid     [DDS_FTR_L2_ORDER_COUNT]SDds__Hq_Order // 买方委托信息
	Ask     [DDS_FTR_L2_ORDER_COUNT]SDds__Hq_Order // 卖方委托信息
}

func (s *SDds_I_Dyn_Ftr_L2) Decode(b []byte) {
	s.Info.Decode(b[:14])
	s.O.Decode(b[14:26])
	s.N1.Decode(b[26:46])
	s.Stf.Decode(b[46:58])
	s.NBuyVol = util.Byte2Int64(b[58:66])
	for i := 0; i < DDS_FTR_L2_ORDER_COUNT; i++ {
		s.Bid[i].Decode(b[66+i*12 : 66+(i+1)*12])
	}
	for i := 0; i < DDS_FTR_L2_ORDER_COUNT; i++ {
		s.Ask[i].Decode(b[126+i*12 : 126+(i+1)*12])
	}
}

// 动态数据——股票指数行情节点， DDS_DYN_DATA_IDX_L1 和 DDS_DYN_DATA_IDX_L2
type SDds_I_Dyn_Stk_Idx struct {
	Info SDds_I_DynBase // 动态数据列表的节点
	O    SDds__Hq_O     // 开盘信息
	N1   SDds__Hq_N1    // 最新价信息
	Z    SDds__Hq_Z     // 股票指数的相关信息：委买总量、委卖总量、涨跌平家数
}

func (s *SDds_I_Dyn_Stk_Idx) Decode(b []byte) {
	s.Info.Decode(b[:14])
	s.O.Decode(b[14:26])
	s.N1.Decode(b[26:46])
	s.Z.Decode(b[46:74])
}

// 动态数据——股票L2逐笔成交结构， DDS_DYN_DATA_STK_T_DEAL 、 DDS_DYN_DATA_STK_T_CANCEL 、 DDS_DYN_DATA_STK_T_ORDER
type SDds_I_Dyn_Stk_Trans struct {
	Info    SDds_I_DynBase // 动态数据列表的节点 此时的 flowid 标识此笔逐笔是本股票的第几笔逐笔
	DwTime  uint32         //hhmmss	由于这是分时结构，而此时 SDds_I_DynBase 中应该是 flow id 有效，这里还需要一个时间域
	NNewest int32          //最新价
	NVolume int64          //成交量
	BtSetNo byte           //成交通道，客户端不需要理会 0:无效  1:A股   2:B股，对于深证L2，这个域恒为0
	YType   byte           //操作类型，见 DDS_OpType.h 中关于 SOpType 的注释
}

func (s *SDds_I_Dyn_Stk_Trans) Decode(b []byte) {
	s.Info.Decode(b[:14])
	s.DwTime = util.Byte2Uint32(b[14:18])
	s.NNewest = util.Byte2Int32(b[18:22])
	s.NVolume = util.Byte2Int64(b[22:30])
	s.BtSetNo = b[30]
	s.YType = b[31]
}

// 动态数据——股票L2最优委托队列结构， DDS_DYN_DATA_STK_ASK_QUEUE 和 DDS_DYN_DATA_STK_BID_QUEUE
//这个不需要标注买卖，因为买卖分为两种动态数据传输(虽然结构一样)
type SDds_I_Dyn_Stk_Order_Queue struct {
	Info        SDds_I_DynBase //动态数据列表的节点
	NTotalCount int32          //总委托数
	NPrice      int32          //委托价格
	NOrderCount int32          //委托数量，标识下面的 order 域有多少个节点
	Order       [DDS_ORDER_QUEUE_COUNT_SH_L2]int64
}

func (s *SDds_I_Dyn_Stk_Order_Queue) Decode(b []byte) {
	s.Info.Decode(b[:14])
	s.NTotalCount = util.Byte2Int32(b[14:18])
	s.NPrice = util.Byte2Int32(b[18:22])
	s.NOrderCount = util.Byte2Int32(b[22:26])
	for i := 0; i < DDS_ORDER_QUEUE_COUNT_SH_L2; i++ {
		s.Order[i] = util.Byte2Int64(b[26+i*8 : 26+(i+1)*8])
	}
}

//动态数据——股票Level1行情节点， DDS_DYN_DATA_STK_HQ_L1
type SDds_I_Dyn_Stk_L1 struct {
	Info    SDds_I_DynBase                         // 动态数据列表的节点
	O       SDds__Hq_O                             // 开盘信息
	N1      SDds__Hq_N1                            // 最新价信息
	NTrans  int64                                  // 成交笔数
	NBuyVol int64                                  // 主买盘，主卖盘=成交量-主买盘
	Bid     [DDS_STK_L1_ORDER_COUNT]SDds__Hq_Order // 买方委托信息
	Ask     [DDS_STK_L1_ORDER_COUNT]SDds__Hq_Order // 卖方委托信息
}

func (s *SDds_I_Dyn_Stk_L1) Decode(b []byte) {
	s.Info.Decode(b[:14])
	s.O.Decode(b[14:26])
	s.N1.Decode(b[26:46])
	s.NTrans = util.Byte2Int64(b[46:54])
	s.NBuyVol = util.Byte2Int64(b[54:62])
	for i := 0; i < DDS_STK_L1_ORDER_COUNT; i++ {
		s.Bid[i].Decode(b[62+i*12 : 62+(i+1)*12])
	}
	for i := 0; i < DDS_STK_L1_ORDER_COUNT; i++ {
		s.Ask[i].Decode(b[122+i*12 : 122+(i+1)*12])
	}
}

//#define DDS_DYN_DATA_TradingPhase						((SDds_DataExType)351)		//产品所处的交易阶段代码	深圳和上海的定义不一样，		SDds_I_Dyn_TradingPhase
type SDds_I_Dyn_TradingPhase struct {
	Info              SDds_I_DynBase // 动态数据列表的节点
	STradingPhaseCode [8]byte        // TradingPhaseCode	产品所处的交易阶段代码	深圳和上海的定义不一样
	// 深圳
	// 第 0 位：
	// S=启动（开市前）		O=开盘集合竞价	T=连续竞价		B=休市
	// C=收盘集合竞价		E=已闭市		H=临时停牌		A=盘后交易
	// 第 1 位：
	// 0=正常状态			1=全天停牌

	// 上海
	//	该字段为8位字符串，左起每位表示特定的含义，无定义则填空格。
	//	第1位：'S'表示启动（开市前）时段，'C'表示集合竞价时段，'T'表示连续交易时段，'B'表示休市时段，'E'表示闭市时段，'P'表示产品停牌，'M'表示可恢复交易的熔断时段（盘中集合竞价），'N'表示不可恢复交易的熔断时段（暂停交易至闭市），'D'表示开盘集合竞价阶段结束到连续竞价阶段开始之前的时段（如有）。
	//	第2位： '0'表示此产品不可正常交易，'1'表示此产品可正常交易，无意义填空格。
	//	第3位：'0'表示未上市，'1'表示已上市。
	//	第4位：'0'表示此产品在当前时段不接受进行新订单申报，'1' 表示此产品在当前时段可接受进行新订单申报。无意义填空格。

}

func (s *SDds_I_Dyn_TradingPhase) Decode(b []byte) {
	s.Info.Decode(b[:14])
	for i := 0; i < 8; i++ {
		s.STradingPhaseCode[i] = b[14+i]
	}
}

//动态数据——股票Level2行情节点， DDS_DYN_DATA_STK_HQ_L2
type SDds_I_Dyn_Stk_L2 struct {
	Info    SDds_I_DynBase                         // 动态数据列表的节点
	O       SDds__Hq_O                             // 开盘信息
	N1      SDds__Hq_N1                            // 最新价信息
	S2      SDds__Hq_S2                            // 持仓量相关信息
	NBuyVol int64                                  // 主买盘，主卖盘=成交量-主买盘
	Bid     [DDS_STK_L2_ORDER_COUNT]SDds__Hq_Order // 买方委托信息
	Ask     [DDS_STK_L2_ORDER_COUNT]SDds__Hq_Order // 卖方委托信息
}

func (s *SDds_I_Dyn_Stk_L2) Decode(b []byte) {
	s.Info.Decode(b[:14])
	s.O.Decode(b[14:26])
	s.N1.Decode(b[26:46])
	s.S2.Decode(b[46:78])
	s.NBuyVol = util.Byte2Int64(b[78:86])
	for i := 0; i < DDS_STK_L1_ORDER_COUNT; i++ {
		s.Bid[i].Decode(b[86+i*12 : 86+(i+1)*12])
	}
	for i := 0; i < DDS_STK_L1_ORDER_COUNT; i++ {
		s.Ask[i].Decode(b[146+i*12 : 146+(i+1)*12])
	}
}

// 动态数据——股票和期货的成交明细结构， DDS_DYN_DATA_REPORT_STK_L1 、 DDS_DYN_DATA_REPORT_STK_L2
type SDds_I_Dyn_Report struct {
	Info   SDds_I_DynBase //动态数据列表的节点 此时的 flowid 标识此笔逐笔是本股票的第几笔逐笔
	N1     SDds__Hq_N1
	CFlag  byte  //最低两位表示主买主卖，0:未知		1:(买价成交)		2:(卖价成交)
	NTrans int64 //在股票的成交明细中，这个域标识当前有多少笔逐笔
}

func (s *SDds_I_Dyn_Report) Decode(b []byte) {
	s.Info.Decode(b[:14])
	s.N1.Decode(b[14:34])
	s.CFlag = b[34]
	s.NTrans = util.Byte2Int64(b[35:43])
}

// 动态数据——不带持仓量信息的分钟线行情节点， DDS_DYN_DATA_MIN_L1 、 DDS_DYN_DATA_MIN_L2
type SDds_I_Dyn_Min struct {
	Info SDds_I_DynBase // 动态数据列表的节点
	N1   SDds__Hq_N1    // 最新价信息
}

func (s *SDds_I_Dyn_Min) Decode(b []byte) {
	s.Info.Decode(b[:14])
	s.N1.Decode(b[14:34])
}

//动态数据——Wav收盘指标， DDS_DYN_DATA_Wav_3Cj_Close_Arg_FENSHI 、 DDS_DYN_DATA_Wav_3Cj_Close_Arg_DAY
type SDds_I_Dyn_Wav_3Cj_Close_Arg struct {
	Info SDds_I_DynBase //动态数据列表的节点

	NZjmc int32 //资金MC		实际数值乘以10000
	NGjld int32 //攻击力度		实际数值乘以10000

	NZhuliD int32 //多空资金多  主力 + 散敢	实际数值乘以10000
	NZhuliK int32 //多空资金空  主力 + 散敢	实际数值乘以10000

	NSGD int32 //散户敢死队多	实际数值乘以10000
	NSGK int32 //散户敢死队空	实际数值乘以10000

	//以下是原来的保留部分
	Reserve [2]int32 //保留域，初始是2
}

func (s *SDds_I_Dyn_Wav_3Cj_Close_Arg) Decode(b []byte) {
	s.Info.Decode(b[:14])
	s.NZjmc = util.Byte2Int32(b[14:18])
	s.NGjld = util.Byte2Int32(b[18:22])
	s.NZhuliD = util.Byte2Int32(b[22:26])
	s.NZhuliK = util.Byte2Int32(b[26:30])
	s.NSGD = util.Byte2Int32(b[30:34])
	s.NSGK = util.Byte2Int32(b[34:38])
	s.Reserve[0] = util.Byte2Int32(b[38:42])
	s.Reserve[1] = util.Byte2Int32(b[42:46])
}

//动态数据——Wav扩展分类成交分时数据，	DDS_DYN_DATA_Wav_3Cj_Fenshi	DDS_DYN_DATA_Wav_3Cj_Day
type SDds_I_Dyn_Wav_3Cj struct {
	Info SDds_I_DynBase //动态数据列表的节点

	Zhu_z SDds__Wav_Cj //主力、主动单(包括机构)
	Zhu_b SDds__Wav_Cj //主力、被动单(包括机构)
	San_z SDds__Wav_Cj //散户和散户敢死队、主动单
	San_b SDds__Wav_Cj //散户、被动单
	Te_b  SDds__Wav_Cj //特大、被动单
	Ge_z  SDds__Wav_Cj //隔价、主动单

	Jg   SDds__Wav_Cj //机构单，不分主动被动
	Sg_z SDds__Wav_Cj //散户敢死队、主动单
}

func (s *SDds_I_Dyn_Wav_3Cj) Decode(b []byte) {
	s.Info.Decode(b[:14])
	s.Zhu_z.Decode(b[14:54])
	s.Zhu_b.Decode(b[54:94])
	s.San_z.Decode(b[94:134])
	s.San_b.Decode(b[134:174])
	s.Te_b.Decode(b[174:214])
	s.Ge_z.Decode(b[214:254])
	s.Jg.Decode(b[254:294])
	s.Sg_z.Decode(b[294:334])
}

// 通过模型计算出来的开平仓
//#define DDS_DYN_DATA_DayModels_CW_Fenshi				((SDds_DataExType)354)		//日线模型合并后的仓位结果		SDds_I_Dyn_Models_CW	盘中类型
//#define DDS_DYN_DATA_HourModels_CW_Fenshi				((SDds_DataExType)355)		//小时模型合并后的仓位结果		SDds_I_Dyn_Models_CW	盘中类型
//#define DDS_DYN_DATA_DayModels_CW_Day					((SDds_DataExType)356)		//日线模型合并后的仓位结果		SDds_I_Dyn_Models_CW	盘后类型
//#define DDS_DYN_DATA_HourModels_CW_Day				((SDds_DataExType)357)		//小时模型合并后的仓位结果		SDds_I_Dyn_Models_CW	盘后类型
type SDds_I_Dyn_Models_CW struct {
	Info SDds_I_DynBase

	//union
	//{
	//	SDds_Int			nEncodeUse;
	//	struct
	//	{
	//		WORD			nCW:8;				// 仓位 0：不持仓，1 - 100，牛，128-255熊
	//		WORD			nFinal:8;			// 是否小时线结束，只有在小时线模型的分时数据中才有效
	//		WORD			wReserved;
	//	};
	//};
	Union1    int32
	NModelId  int32 // 模型ID，只有在小时线的买入时才有效
	NHitPrice int32 // 出击价格

	//union
	//{
	//	SDds_Int				dwReserved;			// 保留域
	//	DWORD					dwPoolIncFlag;			//	为了方便比较和赋值
	//	SPoolIncCWFlag			nPoolIncFlag;			//	轮动增仓标志位，
	//};
	Union2 int32
	//union
	//{
	//	SDds_Int				dwReserved2;		// 保留域2
	//	DWORD					dwPoolSnapFlag;			//	为了方便比较和赋值
	//	SPoolIncCWFlag			nPoolSnapFlag;			//	轮动仓位快照标志位，
	//};
	Union3 int32
}

func (s *SDds_I_Dyn_Models_CW) Decode(b []byte) {
	s.Info.Decode(b[:14])
	s.Union1 = util.Byte2Int32(b[14:18])
	s.NModelId = util.Byte2Int32(b[18:22])
	s.NHitPrice = util.Byte2Int32(b[22:26])
	s.Union2 = util.Byte2Int32(b[26:30])
	s.Union3 = util.Byte2Int32(b[30:34])
}

// D股价活跃度指标
type SDds_I_Dyn_DPHYDArg struct {
	Info SDds_I_DynBase

	IDHYD13 int32 // 股价活跃度13  *　1000
	IDHYD34 int32 // 股价活跃度34  *　1000

	//	SDds_Int				nReserve1;
	NReserve2 int32
}

func (s *SDds_I_Dyn_DPHYDArg) Decode(b []byte) {
	s.Info.Decode(b[:14])
	s.IDHYD13 = util.Byte2Int32(b[14:18])
	s.IDHYD34 = util.Byte2Int32(b[18:22])
	s.NReserve2 = util.Byte2Int32(b[22:26])
}

// 动态数据——K线， DDS_DYN_DATA_KLINE_DAY 和 DDS_DYN_DATA_Kline_1Min 、 DDS_DYN_DATA_Kline_15Min
type SDds_I_Dyn_Kline struct {
	Info SDds_I_DynBase // 动态数据列表的节点
	Ko   SDds__Hq_KO    // 开盘信息
	C    SDds__Hq_C     // 收盘信息
	Stf  SDds__Hq_Stf   // 持仓量
}

func (s *SDds_I_Dyn_Kline) Decode(b []byte) {
	s.Info.Decode(b[:14])
	s.Ko.Decode(b[14:26])
	s.C.Decode(b[26:46])
	s.Stf.Decode(b[46:58])
}

// 过滤结果--对照行业板块的结构
type SDds_Quantitative_ModelFilter struct {
	Info SDds_I_DynBase

	BtFlagA  byte // A级，最严滤网，理应结果最好   分合（松）& 合分   0：不允许过  1：允许过，以下一样
	BtFlagB  byte // B级，个股严格
	BtFlagC  byte // C级，大盘严格
	BtFlagD  byte // D级，最宽松  分合|合分
	NReserve [4]int32
}

func (s *SDds_Quantitative_ModelFilter) Decode(b []byte) {
	s.Info.Decode(b[:14])
	s.BtFlagA = b[14]
	s.BtFlagB = b[15]
	s.BtFlagC = b[16]
	s.BtFlagD = b[17]
	s.NReserve[0] = util.Byte2Int32(b[18:22])
	s.NReserve[1] = util.Byte2Int32(b[22:26])
	s.NReserve[2] = util.Byte2Int32(b[26:30])
	s.NReserve[3] = util.Byte2Int32(b[30:34])
}

const MODE_NIUTOU = 0x01      // 牛头
const MODE_NIUSHEN = 0x02     // 牛身
const MODE_CHAODIE = 0x04     // 超跌
const MODE_ZHENDANG = 0x08    // 振荡
const MODE_ZHENDANG2 = 0x10   // 振荡
const MODE_BOTHCHAODIE = 0x20 // 大盘个股双超跌
// 买入信号标志--模型出击预告
type SDds_Quantitative_Model_RawFlag struct {
	Info SDds_I_DynBase

	DwModel uint32 // 模型，按位与

	NClose int32 //	收盘价

	NPrice50 int32 //	买成率30
	NPrice70 int32 //	买成率50
	NPrice80 int32 //	买成率70
	NPrice85 int32 //	买成率70
	NPrice95 int32 //	买成率70

	NAvgAmount5 int64 //	包括本周期内前5个周期的平均成交额

	//NReserve [4]int32
	NCalculator    int32
	NFinish        int32 // 结束标志
	NCountinueLose int32 //连续多季度亏损
	NReserve1      int32
	NReserve2      [3]int32
}

func (s *SDds_Quantitative_Model_RawFlag) Decode(b []byte) {
	s.Info.Decode(b[:14])
	s.DwModel = util.Byte2Uint32(b[14:18])
	s.NClose = util.Byte2Int32(b[18:22])
	s.NPrice50 = util.Byte2Int32(b[22:26])
	s.NPrice70 = util.Byte2Int32(b[26:30])
	s.NPrice80 = util.Byte2Int32(b[30:34])
	s.NPrice85 = util.Byte2Int32(b[34:38])
	s.NPrice95 = util.Byte2Int32(b[38:42])
	s.NAvgAmount5 = util.Byte2Int64(b[42:50])
	Wt := util.Byte2Int32(b[50:54])
	s.NCalculator = Wt & 127
	s.NFinish = (Wt >> 7) & 1
	s.NCountinueLose = (Wt >> 8) & 1
	s.NReserve1 = (Wt >> 9)
	s.NReserve2[0] = util.Byte2Int32(b[54:58])
	s.NReserve2[1] = util.Byte2Int32(b[58:62])
	s.NReserve2[2] = util.Byte2Int32(b[62:66])
}

const (
	MARKET_GRADE_A = 1
	MARKET_GRADE_B = 2
	MARKET_GRADE_C = 3
	MARKET_GRADE_D = 4
)

// 行情定仓位的结果
type SMarketPositionItem struct {
	BtValid    byte  // 有效数据标志，只针对模型...为0时表示此点无模型出击
	BtGrade    byte  // 评级：MARKET_GRADE_A...
	ICW        int32 // 仓位*1000
	IDayProfit int32 // 日收益*10000
}

func (s *SMarketPositionItem) Decode(b []byte) {
	s.BtValid = b[0]
	s.BtGrade = b[1]
	s.ICW = util.Byte2Int32(b[2:6])
	s.IDayProfit = util.Byte2Int32(b[6:10])
}

/*
type SDds_Quantitative_MarketPosition struct {
	Info SDds_I_DynBase

	ItemMarket SMarketPositionItem // 市场
	ItemModel  SMarketPositionItem

	NBoardId [3]int32 // 拔优的板块ID，从第一名起
	NReserve int32

	//	SDds_Int				nReserve[4];
}

func (s *SDds_Quantitative_MarketPosition) Decode(b []byte) {
	s.Info.Decode(b[:14])
	s.ItemMarket.Decode(b[14:24])
	s.ItemModel.Decode(b[24:34])
	s.NBoardId[0] = Byte2Int32(b[34:38])
	s.NBoardId[1] = Byte2Int32(b[38:42])
	s.NBoardId[2] = Byte2Int32(b[42:46])
	s.NReserve = Byte2Int32(b[46:50])
}*/

const MAX_EXCELLENT_COUNT = 3

const (
	SELL_SHORT_1 = 1
	SELL_SHORT_2 = 2
	SELL_SHORT_3 = 4
	SELL_SHORT_4 = 8
	SELL_SHORT_5 = 16
)

const (
	STATE_0Z_QS     = 1   // 0Z趋势
	STATE_0Z_NT     = 2   // 0Z牛头
	STATE_0Z_ZD     = 4   // 0Z震荡
	STATE_0Z_CD     = 8   // 0Z超跌
	STATE_MARKET_QS = 16  // 五市场趋势
	STATE_MARKET_NT = 32  // 五市场牛头
	STATE_MARKET_ZD = 64  // 五市场震荡
	STATE_MARKET_CD = 128 // 五市场超跌
)

type SDds_Quantitative_MarketPosition struct {
	Info SDds_I_DynBase

	ItemMarket SMarketPositionItem // 市场 //用这个
	ItemModel  SMarketPositionItem

	NBoardId [MAX_EXCELLENT_COUNT]int32 // 拔优的板块ID，从第一名起

	NExitRate int32 // 激流勇退系数*1000

	NSellShort int32 // 卖空标志 SELL_SHORT_1 | ... | SELL_SHORT_5

	NDPStateArg int32 // 大盘状态指标
	NReserve    [3]int32
}

func (s *SDds_Quantitative_MarketPosition) Decode(b []byte) {
	s.Info.Decode(b[:14])
	s.ItemMarket.Decode(b[14:24])
	s.ItemModel.Decode(b[24:34])
	s.NBoardId[0] = util.Byte2Int32(b[34:38])
	s.NBoardId[1] = util.Byte2Int32(b[38:42])
	s.NBoardId[2] = util.Byte2Int32(b[42:46])
	s.NExitRate = util.Byte2Int32(b[46:50])
	s.NSellShort = util.Byte2Int32(b[50:54])
	s.NDPStateArg = util.Byte2Int32(b[54:58])
	s.NReserve[0] = util.Byte2Int32(b[58:62])
	s.NReserve[1] = util.Byte2Int32(b[62:66])
	s.NReserve[2] = util.Byte2Int32(b[66:70])
}

// 质检信息
type SDds_Quantitative_ModelCheck struct {
	Info SDds_I_DynBase

	DwCheckTime uint32 // 校验的时间点

	DwDate uint32 // 买入点日期
	DwTime uint32 // 买入点时间

	NProfit         int32 // 质检收益 * 10000
	NForecastProfit int32 // 预测质检收益 * 10000
	NHoldDay        int32 // 持仓K线根线（非天数）
	NModelType      int32 // 模型类型 MODE_NIUTOU | MODE_NIUSHEN | MODE_CHAODIE | MODE_ZHENDANG

	NReserve [3]int32
}

func (s *SDds_Quantitative_ModelCheck) Decode(b []byte) {
	s.Info.Decode(b[:14])
	s.DwCheckTime = util.Byte2Uint32(b[14:18])
	s.DwDate = util.Byte2Uint32(b[18:22])
	s.DwTime = util.Byte2Uint32(b[22:26])
	s.NProfit = util.Byte2Int32(b[26:30])
	s.NForecastProfit = util.Byte2Int32(b[30:34])
	s.NHoldDay = util.Byte2Int32(b[34:38])
	s.NModelType = util.Byte2Int32(b[38:42])
	s.NReserve[0] = util.Byte2Int32(b[42:46])
	s.NReserve[1] = util.Byte2Int32(b[46:50])
	s.NReserve[2] = util.Byte2Int32(b[50:54])
}

const (
	ModelId_Error     = (0)
	ModelId_NouTou    = (1)
	ModelId_NouShen   = (2)
	ModelId_Chaodie   = (3)
	ModelId_ZhenDang1 = (4)
	ModelId_ZhenDang2 = (5)

	ModelId_BothChaodie = (150)

	ModelId_All         = (201)
	ModelId_All_Chaodie = (202)
)

// 出击信息
type SDds_Quantitative_Model_Hit struct {
	Info SDds_I_DynBase // 动态数据列表的节点

	NHitModelId int32
	NBuildId    int32 // 建仓单号，出击和平仓用同一个Id

	DwDate uint32 // 发生日期  YYYYMMDD
	DwTime uint32 // 发生时间  HHMMSS

	NHitOp int32 // 0：空仓（卖）   1：开仓

	NHitPrice int32 // 价格*1000
	NReserve  [4]int32
}

func (s *SDds_Quantitative_Model_Hit) Decode(b []byte) {
	s.Info.Decode(b[:14])
	s.NHitModelId = util.Byte2Int32(b[14:18])
	s.NBuildId = util.Byte2Int32(b[18:22])
	s.DwDate = util.Byte2Uint32(b[22:26])
	s.DwTime = util.Byte2Uint32(b[26:30])
	s.NHitOp = util.Byte2Int32(b[30:34])
	s.NHitPrice = util.Byte2Int32(b[34:38])
	s.NReserve[0] = util.Byte2Int32(b[38:42])
	s.NReserve[1] = util.Byte2Int32(b[42:46])
	s.NReserve[2] = util.Byte2Int32(b[46:50])
	s.NReserve[3] = util.Byte2Int32(b[50:54])
}

const MAX_CHECK_STAT = 50

// 质检预测统计结果，只有大盘数据，放在0Z上吧
type SDds_Quantitative_ModelCheckStat struct {
	Info        SDds_I_DynBase
	NSuccRate   int32 // 对标成功率 * 10000
	NValidCount int32 // 有效数据个数（不同周期不一样）

	NPrecision [MAX_CHECK_STAT]int32 // 第i根K线质检精度*10000，暂定50个数组，即最多支持50根K线质检预测，第51根为对标点

	NReserve [4]int32
}

func (s *SDds_Quantitative_ModelCheckStat) Decode(b []byte) {
	s.Info.Decode(b[:14])
	s.NSuccRate = util.Byte2Int32(b[14:18])
	s.NValidCount = util.Byte2Int32(b[18:22])
	diff := 22
	for i := 0; i < MAX_CHECK_STAT; i++ {
		s.NPrecision[i] = util.Byte2Int32(b[diff+i*4 : diff+i*4+4])
	}
	diff = diff + 4*MAX_CHECK_STAT
	for i := 0; i < 4; i++ {
		s.NReserve[i] = util.Byte2Int32(b[diff+i*4 : diff+i*4+4])
	}
}

const ModelId_GG_JD_SCD_1 = (1)    //	日_个股_减点_双超跌_1.ghost
const ModelId_GG_JD_SCD_2 = (2)    //	日_个股_减点_双超跌_2.ghost
const ModelId_GG_DPFDJ_1 = (3)     //	日_个股_大盘非加点_1.ghost
const ModelId_GG_DPFDJ_2 = (4)     //	日_个股_大盘非加点_2.ghost
const ModelId_GG_DPFDJ_3 = (5)     //	日_个股_大盘非加点_3.ghost
const ModelId_GG_DPFDJ_4_1 = (6)   //	日_个股_大盘非加点_4_1.ghost
const ModelId_GG_DPFDJ_4_2 = (7)   //	日_个股_大盘非加点_4_2.ghost
const ModelId_GG_DPFDJ_5 = (8)     //	日_个股_大盘非加点_5.ghost
const ModelId_GG_NTJD_1_1 = (9)    //	日_个股_牛头加点_1_1.ghost
const ModelId_GG_NTJD_1_2 = (10)   //	日_个股_牛头加点_1_2.ghost
const ModelId_GG_CDJD_1 = (11)     //	日_个股_超跌加点_1.ghost
const ModelId_GG_CDJD_2 = (12)     //	日_个股_超跌加点_2.ghost
const ModelId_GG_CDJD_3 = (13)     //	日_个股_超跌加点_3.ghost
const ModelId_GG_CDJD_4_1 = (14)   //	日_个股_超跌加点_4_1.ghost
const ModelId_GG_CDJD_4_2 = (15)   //	日_个股_超跌加点_4_2.ghost
const ModelId_GG_CDJD_5 = (16)     //	日_个股_超跌加点_5.ghost
const ModelId_GG_QSJD_NT = (17)    //	日_个股_趋势减点_牛头.ghost
const ModelId_GG_QSJD_NS = (18)    //	日_个股_趋势减点_牛身.ghost
const ModelId_GG_QSJD_CDFT1 = (19) //	日_个股_趋势减点_超跌反弹1.ghost
const ModelId_GG_QSJD_CDFT2 = (20) //	日_个股_趋势减点_超跌反弹2.ghost
const ModelId_GG_QSJD_ZD1 = (21)   //	日_个股_趋势减点_震荡1.ghost
const ModelId_GG_QSJD_ZD2 = (22)   //	日_个股_趋势减点_震荡2.ghost
const ModelId_GG_QSJD_1 = (23)     //	日_个股_趋势加点_1.ghost
const ModelId_GG_QSJD_2 = (24)     //	日_个股_趋势加点_2.ghost
const ModelId_GG_QSJD_3 = (25)     //	日_个股_趋势加点_3.ghost
const ModelId_GG_QSJD_4 = (26)     //	日_个股_趋势加点_4.ghost
const ModelId_GG_QSJD_5 = (27)     //	日_个股_趋势加点_5.ghost
const ModelId_GG_ZDJD_NT = (28)    //	日_个股_震荡减点_牛头.ghost
const ModelId_GG_ZDJD_NS = (29)    //	日_个股_震荡减点_牛身.ghost
const ModelId_GG_ZDJD_CDFT1 = (30) //	日_个股_震荡减点_超跌反弹1.ghost
const ModelId_GG_ZDJD_CDFT2 = (31) //	日_个股_震荡减点_超跌反弹2.ghost
const ModelId_GG_ZDJD_ZD1 = (32)   //	日_个股_震荡减点_震荡1.ghost
const ModelId_GG_ZDJD_ZD2 = (33)   //	日_个股_震荡减点_震荡2.ghost
const ModelId_GG_ZDJD_1 = (34)     //	日_个股_震荡加点_1.ghost
const ModelId_GG_ZDJD_2 = (35)     //	日_个股_震荡加点_2.ghost
const ModelId_GG_ZDJD_3 = (36)     //	日_个股_震荡加点_3.ghost

// 模型出击掩码，三个DWORD，最大支持96个模型，通过（模型ID-1)/32，找到其在数组中位置，通过 1 << ((模型ID-1)%32)，计算其掩码
// 如ID为75的模型，判断其是否出击，先计算其掩码为A = 1<<((75-1)%32)，然后找到其在数组中的下标(75-1)/32，即(A  == (dwModelMask[2] & A))

const PLAY_FIXED_2 = 0   // 固定份额两仓
const PLAY_FIXED_3 = 1   // 固定份额三仓
const PLAY_UNFIXED_2 = 2 // 不定份额两仓
const PLAY_UNFIXED_3 = 3 // 不定份额三仓

type SScoreInfo struct {
	NSuccRate   int32 // 成功率%*1000，如89%的成功率，为89000
	NProfitRate int32 // 收益率%*1000，如5.5%的收益率，为5500
	NMaxLoss    int32 // 最大持仓亏损%*1000，如9%的亏损，为9000
}

func (s *SScoreInfo) Decode(b []byte) {
	s.NSuccRate = util.Byte2Int32(b[:4])
	s.NProfitRate = util.Byte2Int32(b[4:8])
	s.NMaxLoss = util.Byte2Int32(b[8:12])
}

// 财富掌门--模型买入, 20191202
type SDds_I_Quantitative_RawFlag_V2 struct {
	Info SDds_I_DynBase

	NModelMask [2]uint32 // 个股模型掩码

	NClose int32 //	收盘价

	NPrice50 int32 //	买成率30
	NPrice70 int32 //	买成率50
	NPrice80 int32 //	买成率70
	NPrice85 int32 //	买成率70
	NPrice95 int32 //	买成率70

	NAvgAmount5 int64 //	包括本周期内前5个周期的平均成交额

	NCalculator    int32
	NFinish        int32 // 结束标志
	NCountinueLose int32 //连续多季度亏损
	NIn_BR01B00001 int32
	NIn_BR01B00002 int32
	NIn_BR01B00007 int32
	NIn_BR01B00014 int32
	NIn_BR01B00024 int32
	NIn_BR01B02149 int32
	NIn_BR01B00035 int32
	NIn_BR01B00036 int32
	NIn_BR01B00037 int32
	NIn_BR01B06100 int32
	NIn_BR01B06305 int32
	NIn_BR01B06501 int32

	NReserve1 int32
	DwFlowId  uint32
	NReserve2 [2]int32

	ItemFixed2 SScoreInfo //	固定份额两仓的信息，通过个股指标查表得到
}

func (s *SDds_I_Quantitative_RawFlag_V2) Decode(b []byte) {
	s.Info.Decode(b[:14])
	s.NModelMask[0] = util.Byte2Uint32(b[14:18])
	s.NModelMask[1] = util.Byte2Uint32(b[18:22])
	s.NClose = util.Byte2Int32(b[22:26])
	s.NPrice50 = util.Byte2Int32(b[26:30])
	s.NPrice70 = util.Byte2Int32(b[30:34])
	s.NPrice80 = util.Byte2Int32(b[34:38])
	s.NPrice85 = util.Byte2Int32(b[38:42])
	s.NPrice95 = util.Byte2Int32(b[42:46])
	s.NAvgAmount5 = util.Byte2Int64(b[46:54])
	Wt := util.Byte2Int32(b[54:58])
	s.NCalculator = Wt & 127
	s.NFinish = (Wt >> 7) & 1
	s.NCountinueLose = (Wt >> 8) & 1
	s.NIn_BR01B00001 = (Wt >> 9) & 1
	s.NIn_BR01B00002 = (Wt >> 10) & 1
	s.NIn_BR01B00007 = (Wt >> 11) & 1
	s.NIn_BR01B00014 = (Wt >> 12) & 1
	s.NIn_BR01B00024 = (Wt >> 13) & 1
	s.NIn_BR01B00035 = (Wt >> 14) & 1
	s.NIn_BR01B00036 = (Wt >> 15) & 1
	s.NIn_BR01B00037 = (Wt >> 16) & 1
	s.NIn_BR01B02149 = (Wt >> 17) & 1
	s.NIn_BR01B06100 = (Wt >> 18) & 1
	s.NIn_BR01B06305 = (Wt >> 19) & 1
	s.NIn_BR01B06501 = (Wt >> 20) & 1
	s.NReserve1 = (Wt >> 21)
	s.DwFlowId = util.Byte2Uint32(b[58:62])
	s.NReserve2[0] = util.Byte2Int32(b[62:66])
	s.NReserve2[1] = util.Byte2Int32(b[66:70])
	s.ItemFixed2.Decode(b[70:82])
}
